package com.changgou.seckill.timer;

import com.alibaba.fastjson.JSON;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import entity.DateUtil;
import entity.SystemConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 定时任务，将秒杀商品从数据库中存到Redis中
 *
 * @author zhengjd
 * @date 2020/5/22 17:33
 */
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Component
public class SeckillGoodsPushTask {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 定时任务将数据库中审核通过的秒杀商品以值为hash的格式存入到Redis缓存中，分为5个时间段
     */
    @Scheduled(cron = "0/10 * * * * ? ")
    public void loadGoodsPushRedis() {
        //获取当前时间之后的5个时间段
        List<Date> dateMenus = DateUtil.getDateMenus();
        for (Date dateMenu : dateMenus) {
            //将时间转化为字符串格式
            String startTime = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYYMMDDHH);
            //获取对应5个时间段的秒杀商品，并且是审核通过的
            Example example = new Example(SeckillGoods.class);
            //设置查询条件
            Example.Criteria criteria = example.createCriteria();
            //审核状态为1
            criteria.andEqualTo("status", "1");
            //库存大于0
            criteria.andGreaterThan("stockCount", 0);
            //开始时间要大于等于开抢时间
            criteria.andGreaterThanOrEqualTo("startTime", dateMenu);
            //结束时间要小于开抢时间+2个小时
            criteria.andLessThan("endTime", DateUtil.addDateHour(dateMenu, 2));
            //排除之前已经加入到Redis的秒杀商品数据
            Set keys = redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + startTime).keys();
            if (keys != null && keys.size() > 0) {
                criteria.andNotIn("id", keys);
            }
            List<SeckillGoods> seckillGoods = seckillGoodsMapper.selectByExample(example);
            //循环遍历秒杀商品并以hash格式存入到Redis中
            for (SeckillGoods seckillGood : seckillGoods) {
                redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + startTime).put(seckillGood.getId(), seckillGood);
            }

            //设置Redis的key两个小时的过期时间
            redisTemplate.expire(SystemConstants.SEC_KILL_GOODS_PREFIX + startTime, 2, TimeUnit.HOURS);
        }
    }
}
